home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / c / vbcc.lha / vbcc / regs.c < prev    next >
C/C++ Source or Header  |  1997-12-30  |  43KB  |  1,081 lines

  1. /*  $VER: vbcc (regs.c) V0.4    */
  2. /*  Registerzuteilung           */
  3.  
  4. #include "opt.h"
  5.  
  6. static char FILE_[]=__FILE__;
  7.  
  8. #ifndef NO_OPTIMIZER
  9.  
  10. int (*savings)[MAXR+1],regu[MAXR+1];
  11. int *rvlist;
  12.  
  13. struct regp {int treg;struct Var *tvar,*tmp;};
  14. void do_load_parms(struct regp [],struct flowgraph *);
  15. void load_one_parm(int,int,struct Var *,struct Var *,struct flowgraph *);
  16.  
  17. int cmp_savings(const void *v1,const void *v2)
  18. /*  Vergleichsfkt, um rvlist nach savings zu sortieren  */
  19. {
  20.     return savings[*(int *)v2][0]-savings[*(int *)v1][0];
  21. }
  22. int entry_load(struct flowgraph *fg,int i)
  23. /*  Testet, ob die Variable in Register i am Anfang von Block fg geladen    */
  24. /*  werden muss, d.h. ein Vorgaenger sie nicht im selben Register hat.      */
  25. {
  26.     struct flowlist *lp;
  27.     lp=fg->in;
  28.     while(lp){
  29.         if(lp->graph&&lp->graph->regv[i]!=fg->regv[i]&&BTST(lp->graph->av_out,fg->regv[i]->index)) return(1);
  30.         lp=lp->next;
  31.     }
  32.     return(0);
  33. }
  34.  
  35. int exit_save(struct flowgraph *fg,int i)
  36. /*  Testet, ob die Variable in Register i am Ende von Block fg gespeichert  */
  37. /*  werden muss, d.h. der Vorgaenger eines Nachfolgers nicht dieselbe       */
  38. /*  Variable im selben Register hat.                                        */
  39. {
  40.     struct flowlist *lp;
  41.     if((fg->normalout&&(!fg->end||fg->end->code!=BRA))&&BTST(fg->normalout->av_in,fg->regv[i]->index)){
  42.         if(fg->normalout->regv[i]!=fg->regv[i]) return(1);
  43.         lp=fg->normalout->in;
  44.         while(lp){
  45.             if(lp->graph&&lp->graph->regv[i]!=fg->regv[i]) return(1);
  46.             lp=lp->next;
  47.         }
  48.     }
  49.     if(fg->branchout&&BTST(fg->branchout->av_in,fg->regv[i]->index)){
  50.         if(fg->branchout->regv[i]!=fg->regv[i]) return(1);
  51.         lp=fg->branchout->in;
  52.         while(lp){
  53.             if(lp->graph&&lp->graph->regv[i]!=fg->regv[i]) return(1);
  54.             lp=lp->next;
  55.         }
  56.     }
  57.     return(0);
  58. }
  59. void load_reg_parms(struct flowgraph *fg)
  60. /*  Laedt Registerparameter, falls noetig.                              */
  61. {
  62.     int i,j; struct Var *v;
  63.     struct regp regp[MAXR+1]={0};
  64. /*     for(i=1;i<=MAXR;i++){ regp[i].treg=0;regp[i].tvar=0;} */
  65.     for(i=0;i<vcount-rcount;i++){
  66.         v=vilist[i];
  67.         if((v->flags®PARM)&&fg->regv[v->reg]!=v&&(BTST(fg->av_in,i)||(v->flags&USEDASADR))){
  68.       regp[v->reg].tvar=v;
  69.       for(j=1;j<=MAXR;j++)
  70.         if(fg->regv[j]==v) regp[v->reg].treg=j;
  71.     }
  72.     }
  73.     do_load_parms(regp,fg);
  74. }
  75.  
  76. void insert_regs(struct flowgraph *fg1)
  77. /*  Fuegt Registervariablen in die ICs ein.                             */
  78. {
  79.     int i;struct IC *p,*lic=0,*new;struct flowgraph *lfg=0,*fg;
  80.     if(DEBUG&9216) printf("inserting register variables\n");
  81.     fg=fg1;
  82.     while(fg){
  83.         if(DEBUG&8192) printf("block %d:\n",fg->index);
  84.         p=fg->start;
  85.         while(p){
  86.             for(i=1;i<=MAXR;i++){
  87.                 if(!fg->regv[i]) continue;
  88.                 if(p->code==ALLOCREG&&p->q1.reg==i) ierror(0);
  89.                 if((p->q1.flags&(VAR|DONTREGISTERIZE))==VAR&&p->q1.v==fg->regv[i]){
  90.                     p->q1.flags|=REG;
  91.                     p->q1.reg=i;
  92.                 }
  93.                 if((p->q2.flags&(VAR|DONTREGISTERIZE))==VAR&&p->q2.v==fg->regv[i]){
  94.                     p->q2.flags|=REG;
  95.                     p->q2.reg=i;
  96.                 }
  97.                 if((p->z.flags&(VAR|DONTREGISTERIZE))==VAR&&p->z.v==fg->regv[i]){
  98.                     p->z.flags|=REG;
  99.                     p->z.reg=i;
  100.                 }
  101.             }
  102.             if(DEBUG&8192) pric2(stdout,p);
  103.             if(p==fg->end) break;
  104.             p=p->next;
  105.         }
  106.         if(fg->start&&fg->start->code==LABEL) lic=fg->start;
  107.         for(i=1;i<=MAXR;i++){
  108.             if(fg->regv[i]){
  109.                 if(DEBUG&8192){
  110.                     printf("(%s),%ld assigned to %s\n",fg->regv[i]->identifier,zl2l(fg->regv[i]->offset),regnames[i]);
  111.                     if(BTST(fg->av_in,fg->regv[i]->index)) printf("active at the start of block\n");
  112.                     if(BTST(fg->av_out,fg->regv[i]->index)) printf("active at the end of block\n");
  113.                 }
  114.  
  115.                 if(BTST(fg->av_out,fg->regv[i]->index)){
  116.                 /*  Variable beim Austritt aktiv?   */
  117.                     if(exit_save(fg,i)){
  118.                         struct IC *tp;
  119.                         if(DEBUG&8192) printf("\thave to save it at end of block\n");
  120.                         new=mymalloc(ICS);
  121.                         new->line=0;
  122.                         new->file=0;
  123.                         new->code=ASSIGN;
  124.                         new->typf=fg->regv[i]->vtyp->flags;
  125.                         /*  cc  */
  126.                         if(new->typf==0) ierror(0);
  127.                         new->q1.flags=VAR|REG;
  128.                         new->q1.val.vlong=l2zl(0L);
  129.                         new->q1.v=fg->regv[i];
  130.                         new->q1.reg=i;
  131.                         new->q2.flags=0;
  132.                         new->q2.val.vlong=szof(fg->regv[i]->vtyp);
  133.                         new->z.flags=VAR|DONTREGISTERIZE;
  134.                         new->z.val.vlong=l2zl(0L);
  135.                         new->z.v=fg->regv[i];
  136.                         new->q1.am=new->q2.am=new->z.am=0;
  137.                         new->use_cnt=new->change_cnt=0;
  138.                         new->use_list=new->change_list=0;
  139.                         /*  Vor FREEREGs und evtl. Branch+COMPARE/TEST setzen   */
  140.                         if(fg->end){
  141.                             tp=fg->end;
  142.                             while(tp!=fg->start&&tp->code==FREEREG)
  143.                                 tp=tp->prev;
  144.                             if(tp&&tp->code>=BEQ&&tp->code<=BRA){
  145.                                 if(tp->code<BRA){
  146.                                     int c;
  147.                                     do{
  148.                                         tp=tp->prev;
  149.                                         c=tp->code;
  150.                                         if(c!=FREEREG&&c!=COMPARE&&c!=TEST) ierror(0);
  151.                                     }while(c!=COMPARE&&c!=TEST);
  152.                                 }
  153.                                 tp=tp->prev;
  154.                             }
  155.                         }else tp=lic;
  156.                         insert_IC_fg(fg,tp,new);
  157.                     }
  158.                 }
  159.                 if(BTST(fg->av_in,fg->regv[i]->index)){
  160.                     if((fg==fg1||entry_load(fg,i))&&(fg!=fg1||!(fg->regv[i]->flags®PARM))){
  161.                         if(DEBUG&8192) printf("\thave to load it at start of block\n");
  162.  
  163.                         new=mymalloc(ICS);
  164.                         new->line=0;
  165.                         new->file=0;
  166.                         new->code=ASSIGN;
  167.                         new->typf=fg->regv[i]->vtyp->flags;
  168.                         /*  cc  */
  169.                         if(new->typf==0) ierror(0);
  170.                         new->q1.flags=VAR|DONTREGISTERIZE;
  171.                         new->q1.val.vlong=l2zl(0L);
  172.                         new->q1.v=fg->regv[i];
  173.                         new->q2.flags=0;
  174.                         new->q2.val.vlong=szof(fg->regv[i]->vtyp);
  175.                         new->z.flags=VAR|REG;
  176.                         new->z.val.vlong=l2zl(0L);
  177.                         new->z.v=fg->regv[i];
  178.                         new->z.reg=i;
  179.                         new->q1.am=new->q2.am=new->z.am=0;
  180.                         new->use_cnt=new->change_cnt=0;
  181.                         new->use_list=new->change_list=0;
  182.                         insert_IC_fg(fg,lic,new);
  183.                     }
  184.                 }
  185.                 if(!lfg||!lfg->regv[i]) insert_allocreg(fg,lic,ALLOCREG,i);
  186.                 if(!fg->normalout||!fg->normalout->regv[i])
  187.                     insert_allocreg(fg,fg->end?fg->end:lic,FREEREG,i);
  188.             }
  189.         }
  190.         if(fg->end) lic=fg->end;
  191.         lfg=fg;
  192.         fg=fg->normalout;
  193.     }
  194.     load_reg_parms(fg1);
  195. }
  196.  
  197. void do_loop_regs(struct flowgraph *start,struct flowgraph *end)
  198. /*  Macht die Variablenzuweisung in Schleife start-end.                 */
  199. /*  Wenn end==0 Registerzuweisung fuer die ganze Funktion, ansonsten    */
  200. /*  fuer die Schleife, die zum Header start gehoert.                    */
  201. {
  202.     struct flowgraph *g;
  203.     int i,r;
  204.     struct Var *lregs[MAXR+1]={0};
  205.     unsigne